package com.demo.touca.service.job;

import lombok.extern.slf4j.Slf4j;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.job.flow.FlowExecutionStatus;
import org.springframework.batch.core.job.flow.JobExecutionDecider;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.util.Map;
import java.util.UUID;

/**
 * 决策任务
 */
@Slf4j
@Component
public class DeciderJobConfig {

    @Autowired
    private JobBuilderFactory jobBuilderFactory;
    @Autowired
    private StepBuilderFactory stepBuilderFactory;

    private MyDecider myDecider = new MyDecider();

    @Bean("deciderJob")
    public Job deciderJob() {
        return jobBuilderFactory.get("deciderJob")
                .start(step1())
                .next(myDecider)
                .from(myDecider).on("weekend").to(step2())
                .from(myDecider).on("workingDay").to(step3())
                .next(step4())
                // .from(step3()).on("*").to(step4())
                .end()
                .build();
    }

    private Step step1() {
        return stepBuilderFactory.get("step1")
                .tasklet((stepContribution, chunkContext) -> {
                    // 获取Job参数
                    Map<String, Object> paramMap = chunkContext.getStepContext().getJobParameters();
                    log.info("param={}", paramMap);
                    // 在step内设置的参数
                    ExecutionContext executionContext = stepContribution.getStepExecution().getJobExecution().getExecutionContext();
                    executionContext.put("from", "step1");
                    String uuid = UUID.randomUUID().toString();
                    executionContext.put("nonce", uuid);
                    log.info("uuid={}", uuid);
                    System.out.println("执行步骤一操作。。。");
                    return RepeatStatus.FINISHED;
                }).build();
    }

    private Step step2() {
        return stepBuilderFactory.get("step2")
                .tasklet((stepContribution, chunkContext) -> {
                    // 获取Job参数
                    Map<String, Object> paramMap = chunkContext.getStepContext().getJobParameters();
                    log.info("param={}", paramMap);
                    // 获取step内设置的参数
                    Map<String, Object> stepParamMap = chunkContext.getStepContext().getJobExecutionContext();
                    String from = (String) stepParamMap.get("from");
                    String uuid = (String) stepParamMap.get("nonce");
                    log.info("from={},uuid={}", from, uuid);
                    System.out.println("执行步骤二操作。。。");
                    stepContribution.getStepExecution().getJobExecution().getExecutionContext().put("from", "step2");
                    return RepeatStatus.FINISHED;
                }).build();
    }

    private Step step3() {
        return stepBuilderFactory.get("step3")
                .tasklet((stepContribution, chunkContext) -> {
                    // 获取Job参数
                    Map<String, Object> paramMap = chunkContext.getStepContext().getJobParameters();
                    log.info("param={}", paramMap);
                    // 获取step内设置的参数
                    Map<String, Object> stepParamMap = chunkContext.getStepContext().getJobExecutionContext();
                    String from = (String) stepParamMap.get("from");
                    String uuid = (String) stepParamMap.get("nonce");
                    log.info("from={},uuid={}", from, uuid);
                    System.out.println("执行步骤三操作。。。");
                    stepContribution.getStepExecution().getJobExecution().getExecutionContext().put("from", "step3");
                    return RepeatStatus.FINISHED;
                }).build();
    }

    private Step step4() {
        return stepBuilderFactory.get("step4")
                .tasklet((stepContribution, chunkContext) -> {
                    // 获取参数
                    Map<String, Object> paramMap = chunkContext.getStepContext().getJobParameters();
                    log.info("param={}", paramMap);
                    // 获取step内设置的参数
                    Map<String, Object> stepParamMap = chunkContext.getStepContext().getJobExecutionContext();
                    String from = (String) stepParamMap.get("from");
                    String uuid = (String) stepParamMap.get("nonce");
                    log.info("from={},uuid={}", from, uuid);
                    System.out.println("执行步骤四操作。。。");
                    return RepeatStatus.FINISHED;
                }).build();
    }

    class MyDecider implements JobExecutionDecider {
        @Override
        public FlowExecutionStatus decide(JobExecution jobExecution, StepExecution stepExecution) {
            LocalDate now = LocalDate.now();
            DayOfWeek dayOfWeek = now.getDayOfWeek();

            if (dayOfWeek == DayOfWeek.SATURDAY || dayOfWeek == DayOfWeek.SUNDAY) {
                return new FlowExecutionStatus("weekend");
            } else {
                return new FlowExecutionStatus("workingDay");
            }
        }
    }
}
